package weixin.utils;

import cn.stylefeng.guns.base.consts.ConstantsContext;
import cn.stylefeng.roses.core.util.ToolUtil;
import com.alibaba.fastjson.JSONObject;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import weixin.MD5_wx;
import weixin.WeChatApi;



import java.net.InetAddress;
import java.security.MessageDigest;
import java.util.*;

/**
 * @author zds
 * @version 1.0
 * @date 2020/3/26 14:39
 */
public class WXPublicUtils {

    /**
     * 公众号的全局唯一接口调用凭据
     */
    public static String access_token = "";
    /**
     * appid
     */
    public static String APPID = "wxb2a65261781d66a4";
    /**
     * 鉴权秘钥
     */
    public static String APPSECRET = "bc57f8b2ee534cdb2ff276fb983b8b97";
    /**
     * 字符数组
     */
    private static final String hexDigits[] = {"0", "1", "2", "3", "4", "5",
            "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};

    /**
     * 鉴权获取token
     */
    public static void accessToken() {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("appid", APPID);
        paramMap.put("secret", APPSECRET);
        String url = WeChatApi.accessTokemUrl + APPID + "&secret=" + APPSECRET;
        JSONObject jsonObject = JSONObject.parseObject(HttpUtils.sendGetRequest(url, null, paramMap));
        access_token = jsonObject.getString("access_token");
    }

    /**
     * 微信支付签名算法sign
     *
     * @param map 提交报文参数
     * @param key 支付密匙
     * @return
     * @author iceman
     */
    public static String createSign(Map<Object, Object> map, String key) {
        ArrayList<String> list = new ArrayList<String>();
        for (Map.Entry<Object, Object> entry : map.entrySet()) {
            if (entry.getValue() != "") {
                list.add(entry.getKey() + "=" + entry.getValue() + "&");
            }
        }
        int size = list.size();
        String[] arrayToSort = list.toArray(new String[size]);
        Arrays.sort(arrayToSort, String.CASE_INSENSITIVE_ORDER);
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < size; i++) {
            sb.append(arrayToSort[i]);
        }
        String result = sb.toString();
        result += "key=" + key;
        String sign = MD5_wx.MD5Encode(result, "UTF-8").toUpperCase();
        return sign;
    }

    /**
     * map集合参数转换为xml格式
     *
     * @param dataMap 要转换的map对象
     * @return XML格式的字符串
     */
    public static String map2XML(Map<Object, Object> dataMap) {

        StringBuilder strBuilder = new StringBuilder();
        Set<Object> objSet = dataMap.keySet();
        strBuilder.append("<xml>");
        for (Object key : objSet) {
            if (key == null) {
                continue;
            }
            Object value = dataMap.get(key);
            strBuilder.append("<")
                    .append(key.toString())
                    .append(">")
                    .append(value)
                    .append("</")
                    .append(key.toString())
                    .append(">\n");
        }
        strBuilder.append("</xml>");
        return strBuilder.toString();
    }

    /**
     * map集合参数转换为xml格式
     *
     * @param dataMap 要转换的map对象
     * @return XML格式的字符串
     */
    public static String mapXML(MultiValueMap<Object, Object> dataMap) {

        StringBuilder strBuilder = new StringBuilder();
        Set<Object> objSet = dataMap.keySet();
        strBuilder.append("<xml>");
        for (Object key : objSet) {
            if (key == null) {
                continue;
            }
            Object value = dataMap.get(key);
            strBuilder.append("<")
                    .append(key.toString())
                    .append("><![CDATA")
                    .append(value)
                    .append("]></")
                    .append(key.toString())
                    .append(">\n");
        }
        strBuilder.append("</xml>");
        return strBuilder.toString();
    }

    /**
     * 生成随机数
     *
     * @param count 要生成的随机数位数
     * @return 随机数字符串
     */
    public static String createNonceStr(int count) {
        String[] nums = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
                "A", "B", "C", "D", "E", "F"};
        int maxIndex = nums.length - 1;
        int numIndex;
        StringBuilder builder = new StringBuilder(count);
        for (int i = 0; i < count; i++) {
            numIndex = (int) (Math.random() * maxIndex);
            builder.append(nums[numIndex]);
        }
        return builder.toString();
    }

    /**
     * MD5加密
     *
     * @param data   要加密的数据
     * @param encode 加密的编码
     * @return md5字符串
     */
    public static String str2MD5(String data, String encode) {
        String resultString = null;
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            if (encode == null || "".equals(encode)) {
                resultString = byteArrayToHexString(md.digest(data
                        .getBytes()));
            } else {
                resultString = byteArrayToHexString(md.digest(data
                        .getBytes(encode)));
            }
        } catch (Exception exception) {
        }
        return resultString;
    }

    /**
     * byte数组转换16进制字符串
     *
     * @param b 要转换的byte数组
     * @return 16进制字符串
     */
    private static String byteArrayToHexString(byte b[]) {
        StringBuffer resultSb = new StringBuffer();
        for (int i = 0; i < b.length; i++) {
            resultSb.append(byteToHexString(b[i]));
        }

        return resultSb.toString();
    }

    /**
     * byte转换成16进制字符串
     *
     * @param b 要转换的byte
     * @return byte对应的16进制字符串
     */
    private static String byteToHexString(byte b) {
        int n = b;
        if (n < 0) {
            n += 256;
        }
        int d1 = n / 16;
        int d2 = n % 16;
        return hexDigits[d1] + hexDigits[d2];
    }


    /**
     * 获取当前服务器ip
     *
     * @return
     */
    public static String getIp() {
        try {
            InetAddress ia = InetAddress.getLocalHost();
//        String localname=ia.getHostName();
            String localip = ia.getHostAddress();
            return localip;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return "500";
        }
    }

    /**
     * JS签名
     */
    public static JSONObject jsValid(String url,String ticket) {
        if(ToolUtil.isEmpty(ticket)){
            MultiValueMap multiValueMap = new LinkedMultiValueMap();
            String jsapiTicketUrl = WeChatApi.jsapiTicketUrl + WXPublicUtils.access_token + "&type=jsapi";
            String s = HttpUtils.sendGetRequest(jsapiTicketUrl, null, multiValueMap);
            JSONObject jsonObject = JSONObject.parseObject(s);
            ticket = jsonObject.getString("ticket");
        }

        //当前时间的秒数
        long timestame = System.currentTimeMillis() / 1000;
        //使用UUID来当随机字符串
        String nonceStr = UUID.randomUUID().toString().replaceAll("-", "");
        String sign = null;
        try {
            sign = JsApiUtil.sign(ticket, nonceStr, timestame, url);
        } catch (Exception e) {
            e.printStackTrace();
        }
        JSONObject object = new JSONObject();
        object.put("appId", WXPublicUtils.APPID);
        object.put("timestame", timestame);
        object.put("nonceStr", nonceStr);
        object.put("signature", sign);
        object.put("ticket", ticket);
        return object;
    }

}
